﻿using SGIMail.DAL;
using SGIMail.Models;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Mail;
using System.Text;
using System.Threading.Tasks;
using System.Web;

namespace SGIMail.BL
{
    public class MailHelper
    {
        DbAccess dbAccess;
        string senderEmail = "";
        char[] delimiters;
        SmtpClient client = new SmtpClient();

        public MailHelper()
        {
            using (dbAccess = new DbAccess())
            {
                senderEmail = dbAccess.GetIdentity();
            }

            delimiters = new char[]
            {
                ' ',
                ',',
                ';',
            };
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="mvm"></param>
        /// <returns></returns>
        public async Task SendMail(MailOutViewModel mvm)
        {
            //List<string> recipientsList = GetRecipients(mvm.MailRecipients).ToList();
            List<MailMessage> msgList = LinkMessage(mvm);
            client = SetupSMTP(mvm.Password);

            string template;

            //Read template file from the App_Data folder
            using (var sr = new StreamReader(HttpContext.Current.Server.MapPath("\\App_Data\\Templates\\") + "EmailTemplate.txt"))
            {
                template = sr.ReadToEnd();
            }

            using (dbAccess = new DbAccess())
            {
                foreach (var receivingEmail in msgList)
                {
                    await ComposeMail(receivingEmail.To.ToString(), mvm.selectedEventID, receivingEmail.Subject, template, receivingEmail.Body);
                }
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="receiverEmail"></param>
        /// <param name="eventId"></param>
        /// <param name="subject"></param>
        /// <param name="template"></param>
        /// <param name="msgBody"></param>
        /// <returns></returns>
        public async Task ComposeMail(string receiverEmail, int eventId, string subject, string template, string msgBody)
        {
            MailAddress address = new MailAddress(senderEmail);
            MailMessage msg = new MailMessage(senderEmail, receiverEmail);

            string imagePath = dbAccess.GetEventImage(eventId);
            int? id = 0;
            int contactId = 0;

            if ((id = dbAccess.GetContactId(receiverEmail)) == 0)
            {
                Contact contact = new Contact()
                {
                    Name = receiverEmail,
                    Email = receiverEmail,
                };

                await dbAccess.AddContact(contact);
                id = dbAccess.GetContactId(receiverEmail);
            }

            contactId = id.Value;
            string link = GetMailLink(eventId, contactId);

            msg.IsBodyHtml = true;
            msg.Subject = subject;
            msg.Body = string.Format(template, msgBody, link, imagePath);
            msg.DeliveryNotificationOptions = DeliveryNotificationOptions.OnFailure;

            await dbAccess.RegisterEvent(contactId, eventId, Category.Mailed);
            //await client.SendMailAsync(msg);
        }

        /// <summary>
        /// Splits the recipients into a list.
        /// </summary>
        /// <param name="recipients">string containing the recipients.</param>
        /// <returns></returns>
        public string[] GetRecipients(string recipients)
        {
            return recipients.Split(delimiters, StringSplitOptions.RemoveEmptyEntries);
        }

        /// <summary>
        /// Links the standard or personalized message with the recipients.
        /// </summary>
        /// <param name="mvm">ViewModel containing the data for the mailing procedure.</param>
        /// <returns>List with the mail messages to be sent.</returns>
        public List<MailMessage> LinkMessage(MailOutViewModel mvm)
        {
            List<string> recipientsList = GetRecipients(mvm.MailRecipients).ToList();
            List<MailMessage> msgList = new List<MailMessage>();
            MailMessage message;
            string to = "", msg = "";

            foreach (var item in recipientsList)
            {
                to = item;

                foreach (var item2 in mvm.recipients)
                {
                    if (item == item2.Email)
                    {
                        to = item2.Email;

                        if (!string.IsNullOrWhiteSpace(item2.PersonalMessage))
                        {
                            msg = item2.PersonalMessage;
                        }

                        else
                        {
                            msg = mvm.MailMessage;
                        }
                    }

                    else
                        msg = mvm.MailMessage;
                }

                message = new MailMessage(senderEmail, to, mvm.MailSubject, msg);
                message.DeliveryNotificationOptions = DeliveryNotificationOptions.OnFailure;
                msgList.Add(message);
            }

            return msgList;
        }

        /// <summary>
        /// Creates and returns the link to be attached in the mail.
        /// </summary>
        /// <param name="eventId">Event id</param>
        /// <param name="contactId">Contact id</param>
        /// <returns>The link in string format.</returns>
        public string GetMailLink(int eventId, int contactId)
        {
            string link = "http://local.sgidomain.com:49689/MailOut/redirectToRegistration?" + GetEventLinkId(eventId) + "&" + GetContactLinkId(contactId);
            return link;
        }

        /// <summary>
        /// Gets the contact link portion.
        /// </summary>
        /// <param name="contactId">Contact id</param>
        /// <returns>The contact link portion in string</returns>
        public string GetContactLinkId(int contactId)
        {
            dbAccess = new DbAccess();
            return "cid=" + dbAccess.GetContactId(contactId).ToString();
        }

        /// <summary>
        /// Gets the event link portion.
        /// </summary>
        /// <param name="eventId">Event id</param>
        /// <returns>The event link portion in string</returns>
        public string GetEventLinkId(int eventId)
        {
            dbAccess = new DbAccess();
            return "eid=" + dbAccess.GetEventId(eventId).ToString();
        }

        /// <summary>
        /// Sets the SMTP settings.
        /// </summary>
        /// <param name="pw"></param>
        /// <returns>The smtp settings as SmtpClient.</returns>
        public SmtpClient SetupSMTP(string pw)
        {
            SmtpClient client = new SmtpClient();
            client.Host = "smtp.live.com";
            client.Port = 587;
            client.EnableSsl = true;
            client.UseDefaultCredentials = true;
            client.Credentials = new NetworkCredential(dbAccess.GetIdentity(), pw);
            return client;
        }
    }
}
